package com.noah2021.controller;

import com.noah2021.error.BusinessException;
import com.noah2021.error.EmBusinessError;
import com.noah2021.service.model.UserModel;
import com.noah2021.response.CommonReturnType;
import com.noah2021.service.UserService;
import com.noah2021.controller.viewobject.UserVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import static com.noah2021.error.EmBusinessError.PARAMETER_VALIDATION_ERROR;

/**
 * 〈〉
 *
 * @author Noah2021
 * @create 2021/2/5
 * @return
 */
@Controller
@RequestMapping("/user")
@CrossOrigin(allowCredentials = "true", allowedHeaders = "*")
public class UserController extends BaseController{

    @Autowired
    UserService userService;

    @Autowired
    HttpServletRequest httpServletRequest;

    @Autowired
    RedisTemplate redisTemplate;
    //用户登陆接口
    @RequestMapping(value = "/login",method = {RequestMethod.POST},consumes={CONTENT_TYPE_FORMED})
    @ResponseBody
    public CommonReturnType login(@RequestParam(name="telphone")String telphone,
                                  @RequestParam(name="password")String password) throws BusinessException, UnsupportedEncodingException, NoSuchAlgorithmException {
        if(StringUtils.isEmpty(telphone) || StringUtils.isEmpty(password))
            throw new BusinessException(PARAMETER_VALIDATION_ERROR);
        UserModel userModel = userService.validateLogin(telphone, this.encodeByMd5(password));
        String uuidToken = UUID.randomUUID().toString();
        uuidToken = uuidToken.replace("-", "");
        redisTemplate.opsForValue().set(uuidToken, userModel);
        redisTemplate.expire(uuidToken, 1, TimeUnit.HOURS);//设置超时时间

//        this.httpServletRequest.getSession().setAttribute("IS_LOGIN",true);
//        this.httpServletRequest.getSession().setAttribute("LOGIN_USER",userModel);
        return CommonReturnType.create(uuidToken);
    }

    //用户注册接口
    @RequestMapping(value = "/register",method = {RequestMethod.POST},consumes={CONTENT_TYPE_FORMED})
    @ResponseBody
    public CommonReturnType register(@RequestParam(name="telphone")String telphone,
                                     @RequestParam(name="otpCode")String otpCode,
                                     @RequestParam(name="name")String name,
                                     @RequestParam(name="gender")Byte gender,
                                     @RequestParam(name="age")Integer age,
                                     @RequestParam(name="password")String password) throws BusinessException, UnsupportedEncodingException, NoSuchAlgorithmException {
        //验证手机号和对应的otpcode相符合
        //String inSessionOtpCode = (String) this.httpServletRequest.getSession().getAttribute(telphone);
        String inSessionOtpCode = (String) redisTemplate.opsForValue().get(telphone);
        if(!otpCode.equals(inSessionOtpCode)){
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR,"验证码不符合");
        }
        //用户的注册流程
        UserModel userModel = new UserModel();
        userModel.setName(name);
        userModel.setGender(gender);
        userModel.setAge(age);
        userModel.setTelphone(telphone);
        userModel.setRegisterMode("iPhone");
        userModel.setEncrptPassword(this.encodeByMd5(password));
        userService.register(userModel);
        return CommonReturnType.create(null);
    }

    public String encodeByMd5(String str) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        //确定计算方法
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        Base64.Encoder encoder = Base64.getEncoder();
        //加密字符串
        String newstr = encoder.encodeToString(str.getBytes("UTF-8"));
        return newstr;
    }


    /*produces：它的作用是指定返回值类型，不但可以设置返回值类型还可以设定返回值的字符编码；
    consumes： 指定处理请求的提交内容类型（Content-Type），例如application/json, text/html;*/
    @RequestMapping(value = "/getotp",method = {RequestMethod.POST}, consumes = {CONTENT_TYPE_FORMED})
    @ResponseBody
    public CommonReturnType getOtp(@RequestParam("telphone") String telphone){
        Random random = new Random();
        int randomInt = random.nextInt(99999);
        randomInt += 10000;
        String otpCode = String.valueOf(randomInt);
        //手机号和验证码用key-value对的形式保存起来，应当放在redis里面，这里为了简单就输出到控制台上
        //httpServletRequest.getSession().setAttribute(telphone, otpCode);
        redisTemplate.opsForValue().set(telphone, otpCode);
        redisTemplate.expire(telphone, 5, TimeUnit.MINUTES);
        System.out.println("telphone: " + telphone + ", otpCode: "+ otpCode);
        return  CommonReturnType.create(null);
    }

    @RequestMapping("/get")
    @ResponseBody
    public CommonReturnType getUser(@RequestParam("id") int id) throws BusinessException {
        UserModel userModel = userService.getUserById(id);
        if (userModel == null)
            throw new BusinessException(EmBusinessError.USER_NOT_EXIST,"该用户不存在");
        UserVO userVO = convertFromUserModel(userModel);
        return CommonReturnType.create(userVO);
    }

    public UserVO convertFromUserModel(UserModel userModel) {
        if (userModel == null)
            return null;
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(userModel, userVO);
        return userVO;
    }
}